package message.push.util;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import message.push.client.Constants;

import com.cndw.commons.encoder.Base64;
public class Aes {
	private static KeyGenerator keygen;

	private static SecretKey desKey;

	private static Cipher cp;

	private static SecretKeySpec keySpec;

	private static final String DEFAULT_KEY = "(fantadust)!2012@520888)linzi";
	private static final IvParameterSpec iv = new IvParameterSpec("kungfu_fantadust".getBytes());

	private static String lastKey = "";
	

	static {
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		try {
			keygen = KeyGenerator.getInstance("AES");

			cp = Cipher.getInstance("AES/CBC/PKCS5Padding");

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {

			e.printStackTrace();
		}

	}

	private synchronized static byte[] crypt(byte[] data, String key, int type) {
		if (keySpec != null && lastKey.equals(key)) {

		} else {
			try {
				SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
				random.setSeed(key.getBytes());
				keygen.init(128, random);
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (NoSuchProviderException e) {
				e.printStackTrace();
			}
			
			
			desKey = keygen.generateKey();
			byte[] enCodeFormat = desKey.getEncoded();
			keySpec = new SecretKeySpec(enCodeFormat, "AES");
			lastKey = key;
		}

		try {
			cp.init(type, keySpec, iv);
			byte[] enc = cp.doFinal(data);
			return enc;
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static String encrypt(String msg, String key) {
		byte[] enc = crypt(msg.getBytes(Constants.charset), key, Cipher.ENCRYPT_MODE);
		return Base64.encode(enc);
	}

	public static String decrypt(String value, String key) {
		byte[] enc = crypt(Base64.decode(value), key, Cipher.DECRYPT_MODE);
		if (enc == null) {
			return null;
		}
		return new String(enc,Constants.charset);
	}

	public static String encrypt(String msg) {
		return encrypt(msg, DEFAULT_KEY);
	}

	public static String decrypt(String value) {
		return decrypt(value, DEFAULT_KEY);
	}
}
